<template>
  <view class="page-container w-[750rpx] mx-auto bg-[#f5f5f5] min-h-screen">
    <!-- 页头 -->
    <PageHeader title="发布课程" />

    <!-- 表单容器 -->
    <view class="form-container p-[24rpx]">
      <!-- 课程基本信息 -->
      <view class="form-section bg-white rounded-[8rpx] p-[24rpx] mb-[30rpx]">
        <text class="section-title text-[28rpx] font-bold mb-[24rpx] block text-blue-500">课程基本信息</text>

        <!-- 课程标题 -->
        <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">课程标题</text>
          <nut-input v-model="courseForm.title" placeholder="请输入课程标题" class="w-full p-[20rpx] border-[1rpx] border-[#ddd] rounded-[8rpx] text-[24rpx]" />
        </view>

        <!-- 课程简介 -->
        <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">课程简介</text>
          <nut-textarea v-model="courseForm.description" placeholder="请输入课程简介" class="w-full p-[20rpx] border-[1rpx] border-[#ddd] rounded-[8rpx] text-[24rpx]" :min-height="160" />
        </view>
        <!-- 课程封面 -->
        <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">课程封面</text>
          <view class="upload-area border-[1rpx] border-dashed border-[#ddd] rounded-[8rpx] p-[40rpx] text-center cursor-pointer mb-[20rpx]" @click="chooseCourseCover">
            <text class="upload-icon block text-[48rpx] text-blue-500 mb-[10rpx]">+</text>
            <text class="upload-text block text-[24rpx] text-[#666]">点击上传课程封面</text>
            <image :src="courseCover" v-if="courseCover" class="preview-image w-full max-h-[400rpx] mt-[20rpx]" mode="widthFix" />
          </view>
        </view>

        <!-- 课程宣传视频 -->
        <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">课程宣传视频</text>
          <view class="upload-area border-[1rpx] border-dashed border-[#ddd] rounded-[8rpx] p-[40rpx] text-center cursor-pointer mb-[20rpx]" @click="chooseCourseVideo">
            <text class="upload-icon block text-[48rpx] text-blue-500 mb-[10rpx]">+</text>
            <text class="upload-text block text-[24rpx] text-[#666]">点击上传视频</text>
            <text v-if="videoUrl" class="video-info block text-[20rpx] text-[#ff0000] mt-[10rpx]">视频已经上传</text>
            <!-- <video :src="videoUrl" v-if="videoUrl" class="preview-image w-full max-h-[400rpx] mt-[20rpx]" mode="widthFix" /> -->
          </view>
        </view>

        <!-- 课程类型 -->
        <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">课程类型</text>
          <view class="w-full p-[25rpx] border-2 border-gray-200 rounded-[15rpx] text-[28rpx] bg-gray-50 box-border" @click="showCategoryPicker = true">
            {{ categoryText || "请选择课程类型" }}
          </view>
          <nut-popup v-model:visible="showCategoryPicker" position="bottom" round>
            <nut-picker :columns="courseCategory" title="课程类型选择" @confirm="confirm" />
          </nut-popup>
        </view>

        <!-- 学习方式 -->
        <!-- <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">学习方式</text>
          <view class="learning-options flex gap-[20rpx]">
            <view
                class="learning-option flex-1 p-[20rpx] border-[1rpx] border-solid border-[#aaa] rounded-[8rpx] text-center cursor-pointer transition-all duration-200 hover:shadow-md"
                :class="courseForm.online === 1 ? 'bg-blue-500' : ''"
                @click="selectLearningType(1)">
              <text class="block text-[24rpx]" :class="courseForm.online === 1 ? 'text-white' : 'text-gray-500'">线上学习</text>
            </view>
            <view
                class="learning-option flex-1 p-[20rpx] border-[1rpx] border-solid border-[#aaa] rounded-[8rpx] text-center cursor-pointer transition-all duration-200 hover:shadow-md"
                :class="courseForm.online === 0 ? 'bg-blue-500' : ''"
                @click="selectLearningType(0)">
              <text class="block text-[24rpx]" :class="courseForm.online === 0 ? 'text-white' : 'text-gray-500'">线下学习</text>
            </view>
          </view>
        </view> -->

        <!-- 课程价格 -->
        <view class="form-group mb-[30rpx]">
          <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">课程价格 (元)</text>
          <nut-input
            v-model="courseForm.price"
            type="digit"
            placeholder="请输入课程价格，支持小数"
            min="0"
            step="0.01"
            class="w-full p-[20rpx] border-[1rpx] border-[#ddd] rounded-[8rpx] text-[24rpx]"
          />
        </view>
      </view>

      <!-- 课程章节 -->
      <view class="form-section bg-white rounded-[8rpx] p-[24rpx] mb-[30rpx]">
        <text class="section-title text-[28rpx] font-bold mb-[24rpx] block text-[#2196F3]">课程章节</text>

        <view id="lessons-container">
          <!-- 章节列表 - 使用v-for渲染 -->
          <view class="lesson-item bg-[#f9f9f9] rounded-[8rpx] p-[30rpx] mb-[30rpx] relative" v-for="(lesson, index) in lessons" :key="lesson.id">
            <text class="remove-lesson absolute right-[20rpx] top-[20rpx] text-[#f44336] text-[36rpx] cursor-pointer" @click="removeLesson(index)">× </text>

            <!-- 章节标题 -->
            <view class="form-group mb-[30rpx]">
              <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">章节标题</text>
              <nut-input v-model="lesson.title" placeholder="请输入章节标题" class="w-full p-[20rpx] border-[1rpx] border-[#ddd] rounded-[8rpx] text-[24rpx]" />
            </view>

            <!-- 章节封面 -->
            <view class="form-group mb-[30rpx]">
              <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">章节封面 (可选)</text>
              <view class="upload-area bg-white border-[1rpx] border-dashed border-[#ddd] rounded-[8rpx] p-[40rpx] text-center cursor-pointer mb-[20rpx]" @click="chooseLessonCover(index)">
                <text class="upload-icon block text-[48rpx] text-[#2196F3] mb-[10rpx]">+</text>
                <text class="upload-text block text-[24rpx] text-[#666]">点击上传章节封面</text>
                <image :src="lesson.coverUrl" v-if="lesson.coverUrl" class="preview-image w-full max-h-[400rpx] mt-[20rpx]" mode="widthFix" />
              </view>
            </view>

            <!-- 章节视频 -->
            <!-- <view class="form-group mb-[30rpx]">
              <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">章节视频（可选）</text>
              <view
                  class="upload-area border-[1rpx] border-dashed border-[#ddd] rounded-[8rpx] p-[40rpx] text-center cursor-pointer mb-[20rpx]"
                  @click="chooseLessonVideo(index)">
                <text class="upload-icon block text-[48rpx] text-[#2196F3] mb-[10rpx]">+</text>
                <text class="upload-text block text-[24rpx] text-[#666]">点击上传章节视频（单次上传视频最大不超过500mb）</text>

                <video :src="chapterVideo" v-if="chapterVideo" class="video-preview w-full mt-[20rpx]"
                       controls/>
                <text v-if="lesson.videoInfo" class="video-info block text-[20rpx] text-[#666] mt-[10rpx]">{{
                    lesson.videoInfo
                  }}
                </text>
              </view>
            </view> -->

            <!-- 章节时长 -->
            <view class="form-group mb-[30rpx]">
              <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">章节时长（分钟）</text>
              <nut-input v-model="lesson.duration" type="number" placeholder="请输入章节时长，如：45" class="w-full p-[20rpx] border-[1rpx] border-[#ddd] rounded-[8rpx] text-[24rpx]" />
            </view>

            <!-- 章节上课时间 -->
            <view class="form-group mb-[30rpx]">
              <text class="form-label block mb-[16rpx] text-[24rpx] text-[#666]">上课时间</text>
              <view class="w-full p-[25rpx] border-2 border-gray-200 rounded-[15rpx] text-[28rpx] bg-gray-50 box-border" @click="showLessonDateTimePicker(index)">
                {{ lesson.dateTime || "请选择上课时间" }}
              </view>
            </view>
          </view>
        </view>

        <!-- 添加章节按钮 -->
        <nut-button
          type="default"
          @click="addLesson"
          class="add-lesson-btn w-full max-w-[200rpx] !flex !mx-auto p-[20rpx_30rpx] text-[24rpx] rounded-none text-center cursor-pointer select-none mb-[30rpx] border-[1rpx] border-[#2196F3] text-[#2196F3]"
          >添加章节
        </nut-button>

        <!-- 章节上课时间选择器弹窗 -->
        <nut-popup v-model:visible="showDateTimePicker" position="bottom" round>
          <nut-date-picker v-model="dateTimeValue" title="选择上课时间" type="datetime" @confirm="confirmLessonDateTime" @cancel="showDateTimePicker = false" />
        </nut-popup>
      </view>
    </view>
    <!-- <input type="file" ref="fileInput" id="fileInput" @change="chooseLessonVideo2" /> -->
    <view class="fixed bottom-0 left-0 right-0 bg-white p-[20rpx] flex justify-center items-center">
      <nut-button type="primary" @click="submitCourse" class="!w-[540rpx] !flex">发布课程 </nut-button>
    </view>
  </view>

  <!-- Canvas元素已移除，使用document.createElement动态创建 -->
</template>

<script setup>
import { ref } from "vue";
import Taro, { showToast } from "@tarojs/taro";
import { IconFont } from "@nutui/icons-vue-taro";
// import { NutInput, NutTextarea, NutButton } from '@nutui/nutui-taro'
import { post, BASE_URL, getFullPath } from "@/utils/request";
import { uploadBig } from "@/utils/uploadBig";
const fileInput = ref(null);

//上传文件路径
const uploadUrl = "/file/upload";
//上传后的路径
const coverImagePath = ref("");

// Canvas尺寸控制变量已移除，使用document.createElement动态创建

const showAvatarPreview = ref(false);

//课程类型
const courseCategory = ref();
//课程类型选择器开关
const showCategoryPicker = ref(false);
//课程类型选择文本
const categoryText = ref();

//上课时间选择器开关
const showDateTimePicker = ref(false);
//上课时间选择器值
const dateTimeValue = ref(new Date());
//当前编辑的章节索引
const currentLessonIndex = ref(0);

const videoUrl = ref();
const chooseCourseVideo = async () => {
  const res = await Taro.chooseVideo({
    sourceType: ["album", "camera"],
    maxDuration: 60, // 最大60分钟
    camera: "back",
  });
  videoUrl.value = res.tempFilePath;
  const uploadRes = await Taro.uploadFile({
      url: getFullPath("/file/upload"),
      filePath: res.tempFilePath,
      name: "file",
      header: {
        token: Taro.getStorageSync("token") ? Taro.getStorageSync("token") : "",
      },
    });
    Taro.hideLoading();
    const data = JSON.parse(uploadRes.data);
    console.log("data ===", data);
    if (data.code === 0) {
      videoUrl.value = getFullPath(data.data);
      //console.log("targetPathRef",targetPathRef)
      showToast({ title: "上传成功", icon: "success" });
    } else {
      showToast({ title: data.message || "上传失败", icon: "none" });
    }
};
/**
 * 课程基本信息表单数据
 * @type {import('vue').Ref<Object>}
 */
const courseForm = ref({
  title: "", // 课程标题
  coverUrl: "", // 课程封面URL
  price: "", // 课程价格
  description: "", // 课程简介
  type: 1, // 课程类型：1-视频列表，2-线下学习
  cycle: "", // 周期
  cycleType: "", // 周期类型
  teacherName: "", // 老师名称
  teachersIntroduction: "", // 老师介绍
  teacherPic: "", // 老师图片
  online: 0, // 学习方式：0-线下学习，1-线上学习
});

// 周期类型选项
const cycleTypeOptions = ref([
  { text: "天", value: "天" },
  { text: "周", value: "周" },
  { text: "月", value: "月" },
  { text: "年", value: "年" },
]);

// 章节列表
const lessons = ref([]);
//课程封面
const courseCover = ref();
const courseCoverUrl = ref("");
//老师图片
const teacherPhoto = ref();
const teacherPhotoUrl = ref("");
//章节视频
const chapterVideo = ref();

// 返回上一页
const navigateBack = () => {
  Taro.navigateBack(); // 替换 router.back()
};

/**
 * 检查并转换为JPG格式
 * @param {string} filePath - 图片文件路径
 * @returns {Promise<string>} 转换后的图片路径
 */
const checkAndConvertToJpg = async (filePath) => {
  try {
    // 检查文件扩展名
    const fileExtension = filePath.toLowerCase().split(".").pop();

    // 如果已经是JPG格式，直接返回
    if (fileExtension === "jpg" || fileExtension === "jpeg") {
      console.log("图片已经是JPG格式，无需转换");
      return filePath;
    }

    console.log("需要转换格式为JPG，原格式:", fileExtension);

    // 获取图片信息
    const imageInfo = await Taro.getImageInfo({
      src: filePath,
    });

    // 使用 document 创建 Canvas 进行格式转换
    const canvasWidth = imageInfo.width;
    const canvasHeight = imageInfo.height;

    console.log("格式转换，Canvas尺寸:", canvasWidth, "x", canvasHeight);

    // 创建临时Canvas元素
    const canvas = document.createElement("canvas");
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    const ctx = canvas.getContext("2d");

    // 创建图片对象
    const img = new Image();
    img.crossOrigin = "anonymous";

    // 等待图片加载完成
    await new Promise((resolve, reject) => {
      img.onload = () => {
        try {
          // 清除canvas背景
          ctx.clearRect(0, 0, canvasWidth, canvasHeight);

          // 绘制原图
          ctx.drawImage(img, 0, 0, canvasWidth, canvasHeight);

          console.log("格式转换Canvas绘制完成，尺寸:", canvasWidth, "x", canvasHeight);
          resolve();
        } catch (error) {
          reject(error);
        }
      };
      img.onerror = reject;
      img.src = filePath;
    });

    // 将Canvas转换为Blob
    const blob = await new Promise((resolve) => {
      canvas.toBlob(resolve, "image/jpeg", 0.9);
    });

    // 创建临时文件URL
    const tempFilePath = URL.createObjectURL(blob);

    console.log("格式转换成功，临时文件路径:", tempFilePath);
    console.log("导出尺寸:", canvasWidth, "x", canvasHeight);

    return tempFilePath;
  } catch (error) {
    console.error("格式转换失败:", error);
    // 转换失败时返回原图片
    return filePath;
  }
};

/**
 * 压缩图片
 * @param {string} filePath - 图片文件路径
 * @returns {Promise<string>} 压缩后的图片路径
 */
const compressImage = async (filePath) => {
  try {
    // 获取图片信息
    const imageInfo = await Taro.getImageInfo({
      src: filePath,
    });

    console.log("原图尺寸:", imageInfo.width, "x", imageInfo.height);

    // 如果宽度超过1024，则进行压缩（保持原图比例）
    if (imageInfo.width > 1024) {
      const scale = 1024 / imageInfo.width;
      // 使用更精确的计算，避免四舍五入导致的宽高比偏差
      const newHeight = Math.round(imageInfo.height * scale);

      // 验证宽高比是否一致
      const originalRatio = imageInfo.width / imageInfo.height;
      const newRatio = 1024 / newHeight;
      const ratioDiff = Math.abs(originalRatio - newRatio);

      console.log("需要压缩，原尺寸:", imageInfo.width, "x", imageInfo.height);
      console.log("压缩后尺寸:", 1024, "x", newHeight, "(保持比例)");
      console.log("原图宽高比:", originalRatio.toFixed(6));
      console.log("新图宽高比:", newRatio.toFixed(6));
      console.log("宽高比差异:", ratioDiff.toFixed(6), ratioDiff < 0.001 ? "(一致)" : "(不一致)");

      // 使用 document 创建 Canvas 进行图片压缩
      const targetWidth = 1024;
      const targetHeight = newHeight;

      console.log("使用document创建Canvas，尺寸:", targetWidth, "x", targetHeight);

      // 创建临时Canvas元素
      const canvas = document.createElement("canvas");
      canvas.width = targetWidth;
      canvas.height = targetHeight;
      const ctx = canvas.getContext("2d");

      // 创建图片对象
      const img = new Image();
      img.crossOrigin = "anonymous";

      // 等待图片加载完成
      await new Promise((resolve, reject) => {
        img.onload = () => {
          try {
            // 清除canvas背景
            ctx.clearRect(0, 0, targetWidth, targetHeight);

            // 绘制压缩后的图片
            ctx.drawImage(img, 0, 0, targetWidth, targetHeight);

            console.log("Canvas绘制完成，尺寸:", targetWidth, "x", targetHeight);
            resolve();
          } catch (error) {
            reject(error);
          }
        };
        img.onerror = reject;
        img.src = filePath;
      });

      // 将Canvas转换为Blob
      const blob = await new Promise((resolve) => {
        canvas.toBlob(resolve, "image/jpeg", 0.8);
      });

      // 创建临时文件URL
      const tempFilePath = URL.createObjectURL(blob);

      console.log("压缩成功，临时文件路径:", tempFilePath);
      console.log("导出尺寸:", targetWidth, "x", targetHeight);

      console.log("图片压缩完成");
      return tempFilePath;
    } else {
      console.log("图片尺寸合适，无需压缩");
      // 检查是否需要转换格式为JPG
      const needConvertToJpg = await checkAndConvertToJpg(filePath);
      return needConvertToJpg;
    }
  } catch (error) {
    console.error("图片压缩失败:", error);
    Taro.showToast({
      title: "图片压缩失败，使用原图",
      icon: "none",
      duration: 2000,
    });
    // 压缩失败时返回原图片
    return filePath;
  }
};

// 选择课程封面
const chooseCourseCover = async () => {
  try {
    const res = await Taro.chooseImage({
      count: 1,
      sizeType: ["original", "compressed"],
      sourceType: ["album", "camera"],
    });
    // 从选择结果中获取图片的本地临时路径
    const tempFilePath = res.tempFilePaths[0];
    if (!tempFilePath) {
      Taro.showToast({ title: "未选择图片", icon: "none" });
      return;
    }

    // 压缩图片
    const compressedPath = await compressImage(tempFilePath);
    courseCover.value = compressedPath;
    // 调用上传接口，传入章节封面路径变量引用
    await uploadAvatar(compressedPath, 1);
  } catch (err) {
    console.error("选择图片失败", err);
  }
};

// 选择老师图片
const chooseTeacherPic = async () => {
  try {
    const res = await Taro.chooseImage({
      count: 1,
      sizeType: ["original", "compressed"],
      sourceType: ["album", "camera"],
    });
    // 从选择结果中获取图片的本地临时路径
    const tempFilePath = res.tempFilePaths[0];
    if (!tempFilePath) {
      Taro.showToast({ title: "未选择图片", icon: "none" });
      return;
    }

    // 压缩图片
    const compressedPath = await compressImage(tempFilePath);
    teacherPhoto.value = compressedPath;
    // 调用上传接口，传入老师图片引用变量
    await uploadAvatar(compressedPath, 2);
  } catch (err) {
    console.error("选择老师图片失败", err);
  }
};
//上传文件
const uploadAvatar = async (filePath, targetPathRef) => {
  try {
    Taro.showLoading({ title: "上传中..." });
    const uploadRes = await Taro.uploadFile({
      url: getFullPath("/file/upload"),
      filePath,
      name: "file",
      header: {
        token: Taro.getStorageSync("token") ? Taro.getStorageSync("token") : "",
      },
    });
    Taro.hideLoading();
    const data = JSON.parse(uploadRes.data);
    if (data.code === 0) {
      if (targetPathRef === 1) {
        courseForm.value.coverUrl = data.data;
      } else if (targetPathRef === 2) {
        courseForm.value.teacherPic = data.data;
      }
      //console.log("targetPathRef",targetPathRef)
      showToast({ title: "上传成功", icon: "success" });
    } else {
      showToast({ title: data.message || "上传失败", icon: "none" });
    }
  } catch (err) {
    Taro.hideLoading();
    showToast({ title: "上传失败", icon: "none" });
  }
};

// 添加章节
const addLesson = () => {
  lessons.value.push({
    id: Date.now(),
    title: "",
    coverUrl: "",
    videoUrl: "",
    videoInfo: "",
    duration: "45", //时长
    dateTime: "2025-08-29 10:00", //上课时间
  });
};

// 初始化添加一个章节
addLesson();

// 删除章节
const removeLesson = (index) => {
  if (lessons.value.length <= 1) {
    Taro.showToast({
      title: "至少保留一个章节",
      icon: "none",
      duration: 2000,
    });
    return;
  }
  lessons.value.splice(index, 1);
};

// 选择章节封面
const chooseLessonCover = async (index) => {
  try {
    const res = await Taro.chooseImage({
      count: 1,
      sizeType: ["original", "compressed"],
      sourceType: ["album", "camera"],
    });
    const tempFilePath = res.tempFilePaths[0];
    lessons.value[index].coverUrl = tempFilePath;
    // 上传章节封面到服务器
    await uploadLessonCover(tempFilePath, index);
  } catch (err) {
    console.error("选择图片失败", err);
    Taro.showToast({ title: "选择图片失败", icon: "none" });
  }
};
let fileId = 0;
const chooseLessonVideo1 = async (index) => {
  fileId = index;
  console.log("fileInput", fileInput);
  const fileInputElement = document.querySelector('input[type="file"]');
  console.log("fileInputElement", fileInputElement);
  fileInputElement.click();
  // fileInput.value.click();
  // document.getElementById('fileInput').click();
};

const chooseLessonVideo2 = async (e) => {
  let file = e.target.files[0];
  console.log("file", file);
  let res1 = await uploadBig(file, (progress) => {
    console.log("progress", progress);
    lessons.value[fileId].videoInfo = `上传中: ${progress}%`;
  });
  lessons.value[fileId].videoUrl = res1;
  setTimeout(() => {
    lessons.value[fileId].videoInfo = `上传成功: (${formatFileSize(res.size)})`;
  }, 90);
};

// 选择章节视频
const chooseLessonVideo = async (index) => {
  try {
    const res = await Taro.chooseVideo({
      sourceType: ["album", "camera"],
      maxDuration: 3600, // 最大60分钟
      camera: "back",
    });

    lessons.value[index].videoUrl = res.tempFilePath;
    lessons.value[index].duration = res.duration;
    lessons.value[index].videoInfo = `已选择: ${res.duration.toFixed(1)}秒 (${formatFileSize(res.size)})`;

    // 使用分片上传章节视频到服务器
    // await uploadLessonVideoChunked(res.tempFilePath, index, res.duration, res.size)
    console.log("res tempFilePath", res);
    // let file = new File([res.tempFilePath], res.tempFilePath, { type: 'video/mp4' })
    let file = res.originalFileObj;

    // 转为blob,  url作为filePath
    let blob = new Blob([file], { type: "video/mp4" });
    let url = URL.createObjectURL(blob);
    console.log("url", url);

    let res1 = await uploadBig(file, (progress) => {
      console.log("progress", progress);
      lessons.value[index].videoInfo = `上传中: ${progress}%`;
    });
    lessons.value[index].videoUrl = res1;
    setTimeout(() => {
      lessons.value[index].videoInfo = `上传成功: (${formatFileSize(res.size)})`;
    }, 90);
  } catch (err) {
    console.error("选择视频失败", err);
    Taro.showToast({ title: "选择视频失败", icon: "none" });
  }
};

// 格式化文件大小
const formatFileSize = (bytes) => {
  if (bytes === 0) return "0 Bytes";
  const k = 1024;
  const sizes = ["Bytes", "KB", "MB", "GB"];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
};

// 上传章节封面
const uploadLessonCover = async (filePath, index) => {
  try {
    Taro.showLoading({ title: "上传封面中..." });
    const uploadRes = await Taro.uploadFile({
      url: getFullPath("/file/upload"),
      filePath,
      name: "file",
      header: {
        token: Taro.getStorageSync("token") || "",
      },
    });
    Taro.hideLoading();

    const data = JSON.parse(uploadRes.data);
    if (data.code === 0) {
      lessons.value[index].coverUrl = getFullPath(data.data); // 更新为服务器URL
      Taro.showToast({ title: "封面上传成功", icon: "success" });
    } else {
      Taro.showToast({ title: data.message || "封面上传失败", icon: "none" });
    }
  } catch (err) {
    Taro.hideLoading();
    Taro.showToast({ title: "封面上传失败", icon: "none" });
  }
};

/**
 * 分片上传章节视频 - 支持断点续传和降级方案
 * @param {string} filePath - 视频文件路径
 * @param {number} index - 章节索引
 * @param {number} duration - 视频时长(秒)
 * @param {number} size - 文件大小(字节)
 * @param {boolean} enableResume - 是否启用断点续传（可选）
 */
const uploadLessonVideoChunked = async (filePath, index, duration, size, enableResume = false) => {
  try {
    Taro.showLoading({ title: "初始化上传..." });

    // 1. 初始化上传，获取文件标识
    const initRes = await post("/chunk/init");
    if (initRes.code !== 0) {
      throw new Error(initRes.message || "初始化上传失败");
    }

    // 验证返回的数据结构
    if (!initRes.data) {
      throw new Error("初始化上传返回数据为空");
    }

    // 获取文件标识
    const fileId = initRes.data;
    console.log("获取到文件标识:", fileId); // 调试日志

    const chunkSize = 2 * 1024 * 1024; // 2MB分片大小
    let totalChunks = Math.ceil(size / chunkSize);

    // 2. 可选的断点续传检查
    let existingChunks = [];
    if (enableResume) {
      try {
        Taro.showLoading({ title: "检查断点续传..." });
        const checkRes = await post("/chunk/check", { fileId });
        if (checkRes.code === 0 && checkRes.data) {
          existingChunks = Array.isArray(checkRes.data) ? checkRes.data : [];
          console.log("发现已上传分片:", existingChunks);
        }
      } catch (checkError) {
        console.warn("断点续传检查失败，继续正常上传:", checkError);
        existingChunks = [];
      }
    }

    Taro.showLoading({ title: "上传视频中..." });

    // 3. 分片上传 - 使用文件读取实现真正的分片
    let useFallback = false;
    let uploadedChunks = []; // 记录本次上传成功的分片

    try {
      for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
        // 如果启用断点续传且分片已存在，跳过上传
        if (enableResume && existingChunks.includes(chunkIndex)) {
          console.log(`分片${chunkIndex}已存在，跳过上传`);
          uploadedChunks.push(chunkIndex);
          continue;
        }

        // 计算当前分片的起始和结束位置
        const start = chunkIndex * chunkSize;
        const end = Math.min(start + chunkSize, size);

        try {
          // 读取文件分片
          const fileRes = await Taro.getFileSystemManager().readFile({
            filePath: filePath,
            position: start,
            length: end - start,
            success: (res) => res.data,
            fail: (err) => {
              throw new Error(`读取文件分片失败: ${err.errMsg}`);
            },
          });

          // 上传分片
          const uploadRes = await Taro.uploadFile({
            url: getFullPath("/chunk/upload"),
            filePath: fileRes,
            name: "chunk",
            formData: {
              fileId: fileId,
              chunkIndex: chunkIndex,
            },
            header: {
              token: Taro.getStorageSync("token") || "",
            },
          });

          const data = JSON.parse(uploadRes.data);
          if (data.code !== 0) {
            throw new Error(data.message || `分片${chunkIndex + 1}上传失败`);
          }

          // 记录成功上传的分片
          uploadedChunks.push(chunkIndex);

          // 更新进度
          const progress = Math.round(((chunkIndex + 1) / totalChunks) * 100);
          Taro.showLoading({ title: `上传中 ${progress}%` });
        } catch (chunkError) {
          throw new Error(`分片${chunkIndex + 1}处理失败: ${chunkError.message}`);
        }
      }
    } catch (error) {
      console.warn("分片上传失败，使用完整文件上传:", error.message);
      useFallback = true;

      // 备用方案：完整文件上传
      Taro.showLoading({ title: "使用备用方案上传..." });
      const uploadRes = await Taro.uploadFile({
        url: getFullPath("/chunk/upload"),
        filePath: filePath,
        name: "chunk",
        formData: {
          fileId: fileId,
          chunkIndex: 0,
        },
        header: {
          token: Taro.getStorageSync("token") || "",
        },
      });

      const data = JSON.parse(uploadRes.data);
      if (data.code !== 0) {
        throw new Error(data.message || "备用上传失败");
      }

      // 更新为单分片
      totalChunks = 1;
      uploadedChunks = [0]; // 记录备用方案上传成功
    }

    // 4. 合并分片
    Taro.showLoading({ title: "合并分片中..." });
    const mergeRes = await post("/chunk/merge", {
      fileId: fileId,
      fileType: "video",
      totalChunks: totalChunks,
    });

    if (mergeRes.code !== 0) {
      throw new Error(mergeRes.message || "合并分片失败");
    }

    Taro.hideLoading();

    // 更新章节信息 - 根据实际返回数据结构调整
    let finalFileUrl;
    if (typeof mergeRes.data === "string") {
      finalFileUrl = mergeRes.data;
    } else if (mergeRes.data && typeof mergeRes.data === "object" && mergeRes.data.value) {
      finalFileUrl = Array.isArray(mergeRes.data.value) ? mergeRes.data.value[0] : mergeRes.data.value;
    } else {
      finalFileUrl = mergeRes.data;
    }

    if (!finalFileUrl) {
      throw new Error("合并分片后未获取到文件URL");
    }

    lessons.value[index].videoUrl = finalFileUrl;
    lessons.value[index].videoInfo = `上传成功: ${duration.toFixed(1)}秒 (${formatFileSize(size)})${useFallback ? " (备用方案)" : ""}${enableResume && existingChunks.length > 0 ? " (断点续传)" : ""}`;
    Taro.showToast({ title: "视频上传成功", icon: "success" });
  } catch (err) {
    Taro.hideLoading();
    lessons.value[index].videoInfo = "上传失败";
    console.error("分片上传错误:", err); // 调试日志
    Taro.showToast({ title: err.message || "视频上传失败", icon: "none" });
  }
};

// 提交课程
const submitCourse = async () => {
  console.log("courseForm.value", courseForm.value);
  // 验证课程基本信息
  if (!courseForm.value.title.trim()) {
    Taro.showToast({ title: "请填写课程标题", icon: "none" });
    return;
  }
  console.log("courseForm.value", courseForm.value);
  if (!courseForm.value.price || Number(courseForm.value.price) <= 0) {
    Taro.showToast({ title: "请填写有效的课程价格（大于0）", icon: "none" });
    return;
  }

  // 验证学习方式是否已选择
  // if (courseForm.value.online === undefined || courseForm.value.online === null) {
  //   Taro.showToast({title: '请选择学习方式', icon: 'none'})
  //   return
  // }

  // 验证价格格式是否正确（支持两位小数）
  const priceRegex = /^\d+(\.\d{1,2})?$/;
  if (!priceRegex.test(courseForm.value.price)) {
    Taro.showToast({ title: "价格格式不正确，最多支持两位小数", icon: "none" });
    return;
  }

  // 验证章节信息
  if (lessons.value.length === 0) {
    Taro.showToast({ title: "请至少添加一个章节", icon: "none" });
    return;
  }

  // 验证所有章节信息
  for (let i = 0; i < lessons.value.length; i++) {
    const lesson = lessons.value[i];
    if (!lesson.title.trim()) {
      Taro.showToast({ title: `第${i + 1}章请填写章节标题`, icon: "none" });
      return;
    }
    // 章节视频设为非必填，只验证已上传的视频格式
    // if (lesson.videoUrl && lesson.videoUrl.startsWith('http://tmp')) {
    //   Taro.showToast({ title: `第${i + 1}章视频上传失败，请重新上传`, icon: 'none' })
    //   return
    // }
    if (!lesson.duration || !lesson.duration.trim()) {
      Taro.showToast({ title: `第${i + 1}章请填写章节时长`, icon: "none" });
      return;
    }
    if (!lesson.dateTime || !lesson.dateTime.trim()) {
      Taro.showToast({ title: `第${i + 1}章请选择上课时间`, icon: "none" });
      return;
    }
  }

  Taro.showLoading({ title: "发布中..." });

  try {
    // 计算总时长（秒转换为小时，这里假设 lesson.duration 单位是秒，除以 3600 转换为小时，保留合适小数位数，比如 2 位）
    const totalDuration = lessons.value.reduce((sum, lesson) => {
      const minutes = parseInt(lesson.duration) || 0;
      // const durationInHours = durationInSeconds / 3600;
      return sum + minutes;
    }, 0);

    // 提交主数据
    const submitData = {
      title: courseForm.value.title,
      price: courseForm.value.price,
      cover: courseForm.value.coverUrl,
      description: courseForm.value.description,
      introduction: courseForm.value.description,
      type: courseForm.value.type,
      cycle: totalDuration, // 使用总时长作为课时
      cycleType: "分钟",
      teacherName: courseForm.value.teacherName,
      teachersIntroduction: courseForm.value.teachersIntroduction,
      teacherPic: courseForm.value.teacherPic,
      videoUrl: videoUrl.value,
      online: 0, // 添加学习方式字段
    };

    const mainRes = await post("/training/saveMain", submitData);
    if (mainRes.code !== 0) {
      throw new Error(mainRes.message || "保存失败");
    }

    const mainId = mainRes.data;

    // 提交章节数据
    const submitDataLessons = lessons.value.map((lesson) => ({
      title: lesson.title,
      videoUrl: lesson.videoUrl,
      coverUrl: lesson.coverUrl, // 添加章节封面
      duration: lesson.duration, // 章节时长
      dateTime: lesson.dateTime, // 章节上课时间
      trainingId: mainId,
    }));

    const lessonsRes = await post("/training/saveList", submitDataLessons);
    if (lessonsRes.code === 0) {
      Taro.hideLoading();
      Taro.showToast({ title: "课程发布成功", icon: "success" });
      // 发布成功后返回上一页
      setTimeout(() => {
        Taro.navigateBack()
      }, 1500)
    } else {
      throw new Error(lessonsRes.message || "章节保存失败");
    }
  } catch (error) {
    Taro.hideLoading();
    Taro.showToast({ title: error.message || "发布失败", icon: "none" });
  }
};

getDataLabels();

//获取课程类型数据
function getDataLabels() {
  post("/dictionary/trainingLabel").then((res) => {
    courseCategory.value = res.data.map((item) => ({
      ...item.columns,
      text: item.columns.name,
      value: item.columns.id,
    }));
  });
}

/**
 * 课程类型选择器确认事件
 * @param {Object} params - 选择器参数
 * @param {Array} params.selectedValue - 选中的值
 * @param {Array} params.selectedOptions - 选中的选项
 */
const confirm = ({ selectedValue, selectedOptions }) => {
  console.log("选项的value", selectedValue[0]);
  //console.log("选项的参数",selectedOptions[0])
  showCategoryPicker.value = false;
  categoryText.value = selectedOptions[0].name;
  courseForm.value.type = selectedValue[0];
};

/**
 * 显示章节上课时间选择器
 * @param {number} index - 章节索引
 */
const showLessonDateTimePicker = (index) => {
  currentLessonIndex.value = index;
  showDateTimePicker.value = true;
};

/**
 * 章节上课时间选择器确认事件
 * @param {Object} params - 选择器参数
 * @param {Array} params.value - 选中的日期时间数组
 */
const confirmLessonDateTime = (obj) => {
  console.log("obj", obj);
  const value = obj.selectedValue
  console.log("选中的日期时间", value);
  showDateTimePicker.value = false;

  // NutUI 日期选择器返回的是数组格式 [year, month, day, hour, minute]
  if (value && value.length >= 5) {
    const year = value[0];
    const month = String(value[1]).padStart(2, "0");
    const day = String(value[2]).padStart(2, "0");
    const hours = String(value[3]).padStart(2, "0");
    const minutes = String(value[4]).padStart(2, "0");

    const formattedDateTime = `${year}-${month}-${day} ${hours}:${minutes}`;
    lessons.value[currentLessonIndex.value].dateTime = formattedDateTime;
  }
};

/**
 * 选择学习方式
 * @param {number} onlineType - 学习方式：0-线下学习，1-线上学习
 */
const selectLearningType = (onlineType) => {
  courseForm.value.online = onlineType;
};
</script>

<style scoped>
/* UnoCSS已通过类名处理样式，此处无需额外样式 */
</style>
